package de.klenkse.eclipse.ftpsync.synchronizer;

import java.util.HashMap;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;

import de.klenkse.eclipse.ftpsync.ErrorManager;
import de.klenkse.eclipse.ftpsync.FTPSyncSetupException;
import de.klenkse.eclipse.ftpsync.model.FTPConfigEntry;
import de.klenkse.eclipse.ftpsync.model.FTPConfigModel;
import de.klenkse.eclipse.ftpsync.model.FTPSyncModelUtils;

/**
 * This is the main class for synchronization. It handles the resource updates
 * and generates the commands for the synchronizers.
 */
public class SynchronizationManager {

	/**
	 * HashMap used to save the relation from configuration files to models.
	 */
	private HashMap<IFile, FTPConfigModel> configs = new HashMap<IFile, FTPConfigModel>();

	/**
	 * The Mapping from Resource to Command Processor entry.
	 */
	private HashMap<IResource, CommandProcessor> configEntries = new HashMap<IResource, CommandProcessor>();

	/** Constructor. */
	public SynchronizationManager() {
		CommandGenerationHandler handler = new CommandGenerationHandler(this);
		ResourcesPlugin.getWorkspace().addResourceChangeListener(handler);
	}

	/**
	 * This method processes a configuration file and sets up the
	 * synchronization.
	 * 
	 * @param configFile
	 */
	public void addConfigFile(IFile configFile) {
		// a config file contains one or more synchronizations. Each
		// synchronization is contained in one {@link FTPConfigEntry}
		try {
			FTPConfigModel model = FTPSyncModelUtils.openModel(configFile);
			configs.put(configFile, model);
			for (FTPConfigEntry entry : model.getConfigEntries()) {
				addConfigEntry(entry);
			}
		} catch (FTPSyncSetupException e) {
			ErrorManager.addError(e, configFile);
		}
	}

	/**
	 * Gets the config entries.
	 */
	public HashMap<IResource, CommandProcessor> getConfigEntries() {
		return configEntries;
	}

	/** Removes a configuration file. */
	private void removeConfigFile(IFile configFile) {
		FTPConfigModel model = configs.get(configFile);
		if (model == null) {
			return;
		}
		for (FTPConfigEntry entry : model.getConfigEntries()) {
			removeConfigEntry(entry);
		}
		configs.remove(configFile);
	}

	/**
	 * Shuts down the command processor for the configuration entry and removes
	 * the configuration entry
	 */
	private void removeConfigEntry(FTPConfigEntry entry) {
		// TODO: Not implemented
	}

	/** Updates a changed config file. */
	public void updateConfigFile(IFile configFile) {
		removeConfigFile(configFile);
		addConfigFile(configFile);
	}

	/**
	 * Adds and configures a configuration entry.
	 */
	private void addConfigEntry(FTPConfigEntry entry) {
		CommandProcessor commandProcessor = new CommandProcessor(entry);
		if (commandProcessor.isReady()) {
			configEntries.put(commandProcessor.getBaseResource(),
					commandProcessor);
		}
	}

	/**
	 * This method shuts down the synchronization removes the occupied memory.
	 */
	public void shutdown() {
		// TODO: Not implemented.
	}

}
